﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Castle.ActiveRecord;
using Castle.ActiveRecord.Framework.Config;
using Castle.ActiveRecord.Framework;
using System.Reflection;
using System.Data;
using System.Collections;

namespace Matriculex.Testes
{
    public class ActiveRecordSQLLiteConnectionProvider : NHibernate.Connection.DriverConnectionProvider
    {
        private static IDbConnection _connection;

        public override IDbConnection GetConnection()
        {
            if (_connection == null)
                _connection = base.GetConnection();
            return _connection;
        }

        public override void CloseConnection(IDbConnection conn)
        {
        }

        /// <summary> 
        /// Destroys the connection that is kept open in order to keep the in-memory database alive.  Destroying 
        /// the connection will destroy all of the data stored in the mock database.  Call this method when the  
        /// test is complete.  
        /// </summary>  
        public static void ExplicitlyDestroyConnection()
        {
            if (_connection != null)
            {
                _connection.Close();
                _connection = null;
            }
        }

        /// <summary>  
        /// Initializes ActiveRecord and the Database that ActiveRecord uses to store the data.  Call this method  
        /// before the test executes.  
        /// </summary>  
        /// <param name="types">A list of ActiveRecord types that will be created in the database</param>  
        public static void InitializeActiveRecord()
        {
            
            ActiveRecordStarter.ResetInitializationFlag();
            ActiveRecordStarter.Initialize(Assembly.Load("Matriculex.Dominio"), GetMockConfiguration());
            ActiveRecordStarter.DropSchema();
            ActiveRecordStarter.CreateSchema();
        }

        private static IConfigurationSource GetMockConfiguration()
        {
            var properties = new Dictionary<string, string>();
            properties.Add("dialect", "NHibernate.Dialect.SQLiteDialect");
            properties.Add("connection.driver_class", "NHibernate.Driver.SQLite20Driver");
            properties.Add("connection.connection_string", "Data Source=:memory:;Version=3;New=True;");
            properties.Add("connection.provider", ConnectionProviderLocator);
            properties.Add("hibernate.query.substitutions", "true=1;false=0");
            properties.Add("proxyfactory.factory_class","NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle");
            var source = new InPlaceConfigurationSource();
            source.Add(typeof(ActiveRecordBase), properties);
            return source;
        }

        private static string ConnectionProviderLocator
        {
            get { return String.Format("{0}, {1}", TypeOfEnclosingClass.FullName, EnclosingAssemblyName.Split(',')[0]); }
        }

        private static Type TypeOfEnclosingClass
        {
            get { return MethodInfo.GetCurrentMethod().DeclaringType; }
        }

        private static string EnclosingAssemblyName
        {
            get { return Assembly.GetAssembly(TypeOfEnclosingClass).FullName; }
        } 
    }
}
